package pl.edu.pw.stud.ltrzaska.policy.xml;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import pl.edu.pw.stud.ltrzaska.config.AppConfiguration;
import pl.edu.pw.stud.ltrzaska.config.AttributeDefinition;
import pl.edu.pw.stud.ltrzaska.config.Config;
import pl.edu.pw.stud.ltrzaska.policy.entity.Directory;
import pl.edu.pw.stud.ltrzaska.policy.entity.File;
import pl.edu.pw.stud.ltrzaska.policy.entity.Filesystem;
import pl.edu.pw.stud.ltrzaska.policy.entity.FilesystemObject;
import pl.edu.pw.stud.ltrzaska.policy.entity.Group;
import pl.edu.pw.stud.ltrzaska.policy.entity.PatternObject;
import pl.edu.pw.stud.ltrzaska.policy.entity.Person;
import pl.edu.pw.stud.ltrzaska.policy.entity.Policy;
import pl.edu.pw.stud.ltrzaska.policy.entity.PolicyValidator;
import pl.edu.pw.stud.ltrzaska.policy.entity.Sequence;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XmlConverter {
	private static final Logger LOGGER = Logger.getLogger(XmlConverter.class);

	private XmlConverter() {

	}

	private static XStream initialize(XStream xstream) {
		xstream.registerConverter(new FileConverter());
		xstream.registerConverter(new DirectoryConverter());
		xstream.registerConverter(new FilesystemConverter());
		xstream.registerConverter(new PatternObjectConverter());
		xstream.registerConverter(new SequenceConverter());
		xstream.registerConverter(new GroupConverter());

		xstream.alias("policy", Policy.class);
		xstream.alias("filesystem", Filesystem.class);
		xstream.alias("dir", Directory.class);
		xstream.alias("file", File.class);
		xstream.alias("group", Group.class);
		xstream.alias("sequence", Sequence.class);
		xstream.alias("person", Person.class);
		xstream.alias("pattern-object", PatternObject.class);
		xstream.alias("validator", PolicyValidator.class);

		xstream.aliasField("people", Policy.class, "people");
		xstream.aliasField("add-validators-path", Policy.class, "additionalValidatorsPath");
		xstream.aliasField("email-address", Person.class, "emailAddress");
		xstream.useAttributeFor(Person.class, "refName");
		xstream.aliasField("refname", Person.class, "refName");
		xstream.aliasField("system-property", FilesystemObject.class, "systemProperty");
		
		AppConfiguration ac = Config.getAppConfig();
		ArrayList<AttributeDefinition> attrDefs = ac.getAttrDefinitions();
		for(int i=0; i< attrDefs.size(); i++) {
			AttributeDefinition a = attrDefs.get(i);
			if(null == a.getClazz()) {
				a.setClazz(FilesystemObject.class);
			}
			xstream.aliasField(a.getXmlName(), a.getClazz(), a.getJavaName());
		}
		xstream.useAttributeFor(FilesystemObject.class, "refName");
				
		return xstream;
	}

	/**
	 * Zamienia plik w formacie XML na klase polityki poprawnosci.
	 * 
	 * @param file
	 * @return
	 */
	public static Policy toPolicy(String xml) {
		Policy po = null;
		XStream xstream = new XStream(new DomDriver());
		xstream = initialize(xstream);
		try {
			po = (Policy) xstream.fromXML(xml);
		} catch (XStreamException e) {
			LOGGER.error("", e);
		}
		return po;
	}
}
